package editorsvg.editor.formas;

import editorsvg.propiedades.GrupoPropiedades;
import editorsvg.propiedades.PropiedadTextoMultilinea;
import java.awt.Shape;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import org.apache.batik.parser.DefaultPointsHandler;
import org.apache.batik.parser.ParseException;
import org.apache.batik.parser.PointsHandler;
import org.apache.batik.parser.PointsParser;

/**
 * Forma que representa una polilinea.
 * @author Jorge Berjano
 */
public class Polilinea extends Forma {

    private List<Point2D> nodos = new ArrayList<Point2D>();
    private Point2D nodoSiguiente;
    private Path2D path = new Path2D.Double();
    private String puntos = "";    
    private boolean regenerarNodos;
    private GrupoPropiedades grupoPropiedades;

    @Override
    public String getNombreTag() {
        return "polyline";
    }
        
    @Override
    public Shape getShape() {
        return path;
    }
        
    private void agregarAPuntos(Point2D posicion) {
        puntos = puntos + posicion.getX() + "," + posicion.getY() + "\n";
    }
    
    public void iniciar(Point2D posicion) {
        nodos.add(posicion);
        agregarAPuntos(posicion);
        
        nodoSiguiente = (Point2D) posicion.clone();
        nodos.add(nodoSiguiente);
    }

    public void agregarNodo(Point2D posicion) {
        if (nodoSiguiente != null) {
            nodoSiguiente.setLocation(posicion);
            agregarAPuntos(posicion);
        }        
        
        nodoSiguiente = posicion;
        nodos.add(nodoSiguiente);
    }

    public void siguientePosicion(Point2D posicion) {
        nodoSiguiente.setLocation(posicion);
        actualizar();
    }

    public void cerrar() {
        actualizar();
    }

    @Override
    public void actualizar() {
        if (regenerarNodos) {
            parsearPuntos();
        }
        
        path.reset();
        for (Point2D nodo : nodos) {
            if (nodo == nodos.get(0)) {
                path.moveTo(nodo.getX(), nodo.getY());
            } else {
                path.lineTo(nodo.getX(), nodo.getY());
            }
        }
    }

    @Override
    public GrupoPropiedades obtenerPropiedades() {
        if (grupoPropiedades == null) {
            grupoPropiedades = new GrupoPropiedades("Polilinea");
            grupoPropiedades.agregarPropiedad(new PropiedadTextoMultilinea(this, "puntos", "points"));
        }
        return grupoPropiedades;
    }

    public String getPuntos() {
        return puntos;
    }

    public void setPuntos(String puntos) {
        this.puntos = puntos;
        regenerarNodos = true;
    }
    
    /**
     * Parsea el atributo puntos generando la lista de nodos.
     */
    private void parsearPuntos() {
        try {
            nodos.clear();
            if (puntos == null) {
                return;
            }

            PointsParser parser = new PointsParser();
            PointsHandler handler = new DefaultPointsHandler() {

                @Override
                public void point(float x, float y) throws ParseException {
                    nodos.add(new Point2D.Double(x, y));
                }
            };
            parser.setPointsHandler(handler);
            parser.parse(puntos);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
